package com.sxit.tdf.server.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.UUID;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.sxit.tdf.server.entity.File;
import com.sxit.tdf.server.entity.bo.*;
import com.sxit.tdf.server.entity.vo.*;
import com.sxit.tdf.server.exception.TdfException;
import com.sxit.tdf.server.response.R;
import com.sxit.tdf.server.service.IFileBucketService;
import com.sxit.tdf.server.service.IFileService;
import com.sxit.tdf.server.util.OSSUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import javax.websocket.server.PathParam;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 前端控制器
 *
 * @author 橙子高
 * @since 2022-02-23
 */
@RestController
@RequestMapping("/file")
@Tag(name = "FileController", description = "文件上传接口")
public class FileController {

  @Autowired private IFileService fileService;
  @Autowired private IFileBucketService bucketService;

  @Value("${my_oss.file_img}")
  private String fileImg;

  @Operation(summary = "上传文件")
  @PostMapping("uploadFile")
  @SaCheckLogin
  @SaCheckPermission("FILE_UPLOAD:SELECT")
  public R uploadFile(
      @Valid InsertUpLoadFileVo insertUpLoadFileVo, @RequestParam("file") MultipartFile file) {

    if (insertUpLoadFileVo.getIsCurrentUserInfo()) {
      insertUpLoadFileVo.setFileOwnerId(StpUtil.getLoginIdAsString());
    }

    try {
      Boolean aBoolean = fileService.uploadFile(insertUpLoadFileVo);
      if (aBoolean) {
        return R.ok("上传成功");
      } else {
        return R.error("上传失败");
      }

    } catch (Exception e) {
      e.printStackTrace();
      return R.error("该文件已经存在于该文件夹");
    }
  }

  @Operation(summary = "获取全部文件夹信息")
  @GetMapping("getAllFileInfo")
  @SaCheckPermission("FILE_UPLOAD:SELECT")
  public R getAllFileInfo(
      @PathParam("pathCode") String pathCode,
      @PathParam("bucketName") String bucketName,
      @PathParam("FileSuffix") String FileSuffix,
      @PathParam("pageSize") Long pageSize,
      @PathParam("current") Integer current,
      @PathParam("fileOwnUserName") String fileOwnUserName,
      @PathParam("filename") String filename) {
    System.out.println(pageSize);
    System.out.println(fileOwnUserName);
    System.out.println(filename);
    System.out.println(FileSuffix);

    if (pageSize == null) {
      pageSize = 10L;
      current = 1;
    }
    List<FileInfoBo> list =
        fileService.getAllFileInfo(
            pathCode, bucketName, FileSuffix, pageSize, fileOwnUserName, current, filename);
    return R.ok().put("data", list);
  }

  @Operation(summary = "删除文件")
  @PostMapping("deleteFile")
  @SaCheckPermission("FILE_UPLOAD:DELETE")
  public R deleteFile(@Valid @RequestBody DeleteFileVo deleteFileVo) {

    Boolean delete = fileService.deleteById(deleteFileVo.getId());

    if (delete) {
      return R.ok("删除成功");
    } else {
      return R.error("删除失败");
    }
  }

  @Operation(summary = "获取当前文件的类型")
  @GetMapping("/getFileSuffix")
  public R getFileSuffix() {
    List<String> suffixs = fileService.getSuffix();
    return R.ok().put("data", suffixs);
  }

  @Operation(summary = "获取线下储存的文件信息")
  @PostMapping("/getStoreFileInfo")
  @SaCheckPermission("FILE_MEMORY:SELECT")
  public R getStoreFileInfo(@Valid @RequestBody SiftStoreFileVo siftStoreFileVo) {

    String ids = siftStoreFileVo.getIds();
    List<Integer> integers = JSON.parseArray(ids, Integer.class);

    List<SimpleFileStoreInfo> list = fileService.getStoreFileInfo(integers);

    return R.ok().put("data", list);
  }

  @Operation(summary = "获取存储文件的信息")
  @GetMapping("/getStoreFileById")
  @SaCheckPermission("FILE_MEMORY:SELECT")
  public R getStoreFileById(@RequestParam("id") String id) {
    StoreFileInfoBo data = fileService.getStoreFileById(id);
    return R.ok().put("data", data);
  }

  @Operation(summary = "修改存储文件的信息")
  @PostMapping("updateStoreFileInfo")
  @SaCheckPermission("FILE_MEMORY:UPDATE")
  public R updateStoreFileInfo(@Valid @RequestBody SiftStorageFileInfoVo siftStorageFileInfoVo) {

    File file = new File();
    file.setId(siftStorageFileInfoVo.getId());
    System.out.println("-----" + siftStorageFileInfoVo.getId());
    if (StringUtils.isNotBlank(siftStorageFileInfoVo.getFileName())) {
      file.setFileName(siftStorageFileInfoVo.getFileName());
    }

    if (siftStorageFileInfoVo.getStorageName() != null) {
      file.setFileStorageId(siftStorageFileInfoVo.getStorageName());
    }

    if (StringUtils.isNotBlank(siftStorageFileInfoVo.getUserName())) {
      file.setFileOwnerId(siftStorageFileInfoVo.getUserName());
    }
    if (StringUtils.isNotBlank(siftStorageFileInfoVo.getFileDescribe())) {
      file.setFileDescribe(siftStorageFileInfoVo.getFileDescribe());
    }
    boolean update = fileService.updateById(file);
    if (update) {
      return R.ok("修改成功");
    } else {
      return R.error("修改失败");
    }
  }

  @Operation(summary = "上传存储室文件信息")
  @PostMapping("insertStorageFileInfo")
  @Transactional
  @SaCheckPermission("FILE_MEMORY:INSERT")
  public R insertStorageFileInfo(
      @Valid InsertStorageFileInfoVo insertStorageFileInfoVo,
      @RequestParam("file") MultipartFile file) {

    File f = new File();
    f.setFileStorageId(insertStorageFileInfoVo.getStorageName());
    f.setFileType("2");
    f.setFileDescribe(insertStorageFileInfoVo.getFileDescribe());
    f.setFileOssPath(fileImg + file.getOriginalFilename());
    f.setFileName(insertStorageFileInfoVo.getFileName());
    f.setIsDelete(0);
    f.setFileSuffix("线下文档");
    f.setFileRealName(file.getOriginalFilename());
    f.setCreateTime(LocalDateTime.now());
    f.setFileOwnerId(insertStorageFileInfoVo.getUserName());

    String filename = file.getOriginalFilename();
    String ext = filename.substring(filename.lastIndexOf(".") + 1);

    String uuidFileName = UUID.fastUUID() + "." + ext;
    f.setFileOssPath(fileImg + uuidFileName);
    try {
      boolean save = fileService.save(f);
      new OSSUtil().uploadFile("sxit-file-img", "", uuidFileName, file.getBytes());
      if (save) {
        return R.ok("保存成功");
      } else {
        return R.error("保存失败");
      }

    } catch (Exception e) {
      e.printStackTrace();
      throw new TdfException("创建失败");
    }
  }

  @Operation(summary = "删除文件")
  @GetMapping("deleteStoreFileById")
  @Transactional
  @SaCheckPermission("FILE_MEMORY:DELETE")
  public R deleteStoreFileById(@RequestParam("id") String id) {
    File byId = fileService.getById(id);
    String fileRealName = byId.getFileRealName();
    Boolean delete = fileService.removeById(id);

    try {
      new OSSUtil().deleteFile("sxit-file-img", "", fileRealName);
    } catch (Exception e) {
      e.printStackTrace();
      throw new TdfException("删除失败");
    }

    if (delete) {
      return R.ok("删除成功");
    } else {
      return R.error("删除失败");
    }
  }

  @GetMapping("addFileDownload")
  @Operation(summary = "更新文件下载次数")
  @Transactional
  public R addFileDownload(@RequestParam("id") String id) {

    fileService.addFileDownload(id);

    return R.ok();
  }

  @Operation(summary = "获取文件全部信息")
  @PostMapping("getComplexFileInfo")
  @SaCheckLogin
  @SaCheckPermission("FILE_SEARCH:SELECT")
  public R getComplexFileInfo(@RequestBody SiftFileInfoVo siftFileInfoVo) {

    IPage<ComplexFileDataBo> list = fileService.getComplexFileInfo(siftFileInfoVo);

    return R.ok().put("data", list.getRecords()).put("total", list.getTotal());
  }

  @Operation(summary = "获取全部文件的类型")
  @GetMapping("getFileAllSuffix")
  public R getFileAllSuffix() {
    List<String> suffixs = fileService.getALLSuffix();
    return R.ok().put("data", suffixs);
  }

  @Operation(summary = "获取私人文件列表")
  @GetMapping("getPrivateFileList")
  public R getPrivateFileList() {

    String userId = StpUtil.getLoginIdAsString();

    List<PrivateFileListBo> list = fileService.getPrivateFileList(userId);

    return R.ok().put("data", list);
  }

  @Operation(summary = "上传私人文件")
  @PostMapping("uploadPrivateFile")
  public R uploadPrivateFile(
      @Valid UpLoadPrivateFileVo upLoadPrivateFileVo, @RequestParam("file") MultipartFile file)
      throws IOException {

    String userId = StpUtil.getLoginIdAsString();

    boolean isUploadFile = fileService.UpLoadPrivateFileVo(userId, upLoadPrivateFileVo, file);

    return R.ok();
  }
}
